Imports System.Threading
Imports System.Data.SqlClient
Imports System.IO
Imports System.ServiceProcess
Imports System.ComponentModel
Imports System.Configuration.Install
Imports System.Xml
Imports System.Text
Imports System.Configuration
Imports System.Windows.Forms
Imports System.Reflection

<System.ComponentModel.RunInstallerAttribute(True)> _
Public Class MyInstallation
    Inherits System.Configuration.Install.Installer
    Dim Cnstr As String = "Initial Catalog=master;Data Source=(local)\PHARMAINSTANCE;Trusted_Connection=true"
    Dim sMSDEsvc As String = "MSSQL$PHARMAINSTANCE" 
    Dim fs As New FileStream(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) & "\" & Assembly.GetExecutingAssembly.GetName().Name.ToString() & ".log", FileMode.Create, FileAccess.Write) 'declaring a FileStream and creating a word document file named file with 
    Dim sw As New StreamWriter(fs) 'access mode of writing    

#Region "    Component Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Component Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Installer overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Component Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Component Designer
    'It can be modified using the Component Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container
    End Sub

#End Region

    Public Overrides Sub Install(ByVal stateSaver As System.Collections.IDictionary)

        Try
            sw.BaseStream.Seek(0, SeekOrigin.End) 'creating a new StreamWriter and passing the filestream object fs as argument
            'the seek method is used to move the cursor to next position to avoid text to be
            'overwritten                    

            MyBase.Install(stateSaver)
            sw.WriteLine("/*=========================================================================================*/ ")
            sw.WriteLine("/*                   *** Welcome To Rx-Office Pharma Setup Programm ***                    */ ")
            sw.WriteLine("/* This is the Pharma.log file, containing an outline of installation details.             */ ")
            sw.WriteLine("/* and will use during the UNINSTALL if asked to do so.                                    */ ")
            sw.WriteLine("/*=========================================================================================*/ ")
                        
            sw.WriteLine("The typical outline of installation details will look like this:")            
            WriteLog("Beginning Rx-Office Pharma install...")
            'sw.WriteLine("*** Installation Path:- " & Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))

            If Not ISEngineInstalled() Then 'Engine Installation 
                WriteLog("Database Engine could not be found please install the HRAA Database.")
            Else
                WriteLog("Database Engine is Installed on Your Computer")
            End If

            If Not StartUPSVC(sMSDEsvc) Then 'Database Service Start 
                WriteLog("Could not start service, Please restart your computer and rerun application")
            Else
                WriteLog("Database Service is Started")
            End If

            If IsDBExist() Then 'Check Database Exist or Not If Exist then Replace and If Not Exist then Attach Databse.  
                WriteLog("Database Configered Successfully")
            Else
                WriteLog("Error --Database Creation")
            End If

            Call WriteConfig() 'Writing Default Values to the Config File.

            sw.WriteLine("Completed Rx-Office Pharma installation")
            sw.WriteLine("*=========================================================================================*/")
            sw.WriteLine("/* End of comments section.                                                               */")
            sw.WriteLine("/*========================================================================================*/")
            'MessageBox.Show("Installation Process Is Ends")
            sw.Close()          'closing the file

        Catch exc As Exception
            WriteLog("Error performing while installer tasks - " & exc.ToString())
            'MessageBox.Show("Error performing installer tasks - " & exc.ToString())
            sw.Close()
        End Try

    End Sub
#Region "User Code"
    Public Function ISEngineInstalled()
        If ServiceInstalled(sMSDEsvc) Then
            Return True
        Else
            Return False
        End If
    End Function

    Private Function ServiceInstalled(ByVal s As String) As Boolean
        Try
            Dim controllers() As ServiceController = ServiceController.GetServices
            Dim nNum As Integer = controllers.Length
            Dim i As Integer = 0           
            Do While (i <= (nNum - 1))
                Application.DoEvents()
                If (controllers(i).ServiceName.ToUpper = s.ToUpper) Then
                    Return True
                End If
                i += 1
            Loop
            WriteLog("Database Engine is Installed on your Computer")
            Return False
        Catch ex As Exception
            WriteLog("Error-- While Installing Engine" & ex.ToString())
        End Try
    End Function
    Public Function IsDBExist()

        Try
            Dim controllers As ServiceController() = ServiceController.GetServices
            Dim bfound As Boolean

            Dim cn As SqlConnection = New SqlConnection(Cnstr)

            cn.Open()

            Dim cmd As SqlCommand = New SqlCommand("  exec sp_databases", cn)

            Dim dr As SqlDataReader

            cmd.CommandTimeout *= 600

            cmd.Connection = cn

            dr = cmd.ExecuteReader

            bfound = False

            Do While dr.Read
                Application.DoEvents()

                If dr(0).ToString.ToUpper = "NGSPaintsDB".ToUpper Then
                    bfound = True
                    Return True
                End If
            Loop

            dr.Close()
            cn.Close()

            If Not bfound Then
                Call RunSQLScript()
            Else
                WriteLog("The DataBase NGSPaintsDB is allready Exist on Your Computer")
            End If

            Return True

        Catch exc As Exception
            WriteLog("Could not configure the Database, please restart your computer and try again." & exc.ToString())
            'MessageBox.Show("Could not configure the Database, please restart your computer and try again." & exc.ToString())
            Return False
        End Try
    End Function
   
    Public Function StartUPSVC(ByVal s As String) As Boolean

        Dim controllers As ServiceController() = ServiceController.GetServices
        Dim nNum As Integer = controllers.Length
        Dim i As Integer

        Try
            For i = 0 To nNum - 1

                If controllers(i).ServiceName.ToUpper = s.ToUpper Then
                    If controllers(i).Status <> ServiceControllerStatus.Running Then
                        If controllers(i).Status <> ServiceControllerStatus.Running Then
                            Application.DoEvents()
                            controllers(i).Start()
                        End If
                        controllers(i).WaitForStatus(ServiceControllerStatus.Running)
                        Application.DoEvents()
                    End If
                    Return True
                End If
                Application.DoEvents()
            Next

        Catch exc As Exception
            WriteLog("Microsoft Database Engine could not start, please contact your software vendor" & exc.ToString())            
            Return False
        End Try

    End Function
    Sub RunSQLScript()

        Try
            Dim cn As SqlConnection = New SqlConnection(Cnstr)

            'cn.Open()

            'Dim server As SQLDMO.SQLServer2Class
            'server = New SQLDMO.SQLServer2Class()

            'Dim spath As String = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)           
            'Dim dbname As String = "NGSPaintsDB"
            'Dim dbfile As String = "" & spath & "\data\NGSPaintsDB.mdf"
            'Dim dbfile1 As String = "" & spath & "\data\NGSPaintsDB_log.LDF"

            'Dim cmd As SqlCommand = New SqlCommand("   EXEC sp_attach_db @dbname = N'NGSPaintsDB',@filename1 = N'" & dbfile & "', @filename2 = N'" & dbfile1 & "'", cn)

            'cmd.CommandTimeout *= 600

            'cmd.Connection = cn

            'cmd.ExecuteNonQuery()

            'cn.Close()

            'WriteLog("Database Is Attached Successfully")

        Catch ex As Exception
            WriteLog("Error---Problem While Database Attachement" & ex.ToString())            
        End Try
    End Sub

    Sub WriteConfig()

        Try
            Dim appConfigPath As String = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
            appConfigPath &= "\Pharmacy.exe.config"

            ' Write the path to the app.config file
            Dim doc As XmlDocument = New XmlDocument()
            doc.Load(appConfigPath)
            Dim node, node1, node2 As XmlNode
            node = doc.SelectSingleNode("configuration")
            node1 = node.SelectSingleNode("appSettings")

            For Each node2 In node1.ChildNodes
                If node2.NodeType = XmlNodeType.Element Then
                    Select Case node2.Attributes("key").Value
                        Case "DbName"
                            node2.Attributes("value").Value = "NGSPaintsDB"
                        Case "Server"
                            node2.Attributes("value").Value = "(local)\PHARMAINSTANCE"
                        Case "UID"
                            node2.Attributes("value").Value = "sa"
                        Case "PWD"
                            node2.Attributes("value").Value = "redhead"
                    End Select
                End If
            Next

            Try
                doc.Save(appConfigPath)
                WriteLog("Changes With Config File Is Success")                
            Catch ex As Exception
                WriteLog("Error--While Writing Config File" & ex.ToString())                
            End Try

        Catch ex As FormatException
            WriteLog("Error--While Writing Config File" & ex.ToString())
        End Try
    End Sub

    Public Sub WriteLog(ByVal mesg As String)
        Try
            sw.WriteLine(Date.Now.Date & vbTab & Format(Now, "hh:mm:ss tt") & vbTab & mesg)
        Catch ex As Exception
            WriteLog(ex.ToString())
        End Try
    End Sub
#End Region

End Class
